/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package rsexplorer.debugger;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.event.TreeExpansionEvent;
import rsexplorer.rstree.ArrayFieldTreeNode;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import javax.swing.JPopupMenu;
import javax.swing.JTree;
import javax.swing.event.TreeExpansionListener;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import rsexplorer.rstree.ClassTreeNode;
import rsexplorer.tree.SortableTreeNode;

public class DataTree extends JTree implements MouseListener, TreeExpansionListener {

    private ArrayList<TreeNode> expandedClasses;
    private Thread expandedUpdateThread;

    public DataTree(TreeNode rootNode) {
        this(new DefaultTreeModel(rootNode));
    }

    public DataTree(TreeModel newModel) {
        super(newModel);

        expandedClasses = new ArrayList<TreeNode>();

        addMouseListener(this);
        addTreeExpansionListener(this);

        //this.setCellRenderer(new CellRender());

        Thread thread = new Thread(new Runnable() {

            public void run() {
                while (true) {
                    if (expandedClasses.size() > 0) {
                        for (int i = 0; i < expandedClasses.size(); i++) {
                            ClassTreeNode tn = (ClassTreeNode)expandedClasses.get(i);

                            if (tn instanceof ClassTreeNode) {
                                tn.update(null, null);
                                ((DefaultTreeModel) treeModel).nodeChanged(tn.getParent());
                            }
                        }
                    }
                    try {
                        Thread.currentThread().sleep(1000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        thread.start();
    }

    public void mouseClicked(MouseEvent e) {
    }

    public void mousePressed(MouseEvent e) {
        if (e.getButton() == MouseEvent.BUTTON3) {
            TreePath tp = getClosestPathForLocation(e.getX(), e.getY());

            TreeNode tn = (TreeNode) tp.getLastPathComponent();

            if (tn == null)
                return;

            setSelectionPath(tp);

            JPopupMenu popup = new JPopupMenu();
            if (tn instanceof ArrayFieldTreeNode) {
                final ArrayFieldTreeNode aftn = (ArrayFieldTreeNode) tn;
                popup.add("Show all indicies").addActionListener(new ActionListener() {

                    public void actionPerformed(ActionEvent e) {

                        String s = String.valueOf((char) 34);
                        ArrayFieldTreeNode ntn = new ArrayFieldTreeNode((aftn.arrayToBig() ? aftn.toString().replace("(", s + s).split(" " + s)[0] : aftn.toString()), aftn.getFieldObject(), null, Integer.MAX_VALUE);
                        SortableTreeNode parent = (SortableTreeNode) aftn.getParent();

                        parent.add(ntn);
                        parent.remove(aftn);

                        ((DefaultTreeModel) treeModel).reload(parent);
                    }
                });
            }

            popup.add("Cancel");
            popup.show(this, e.getX(), e.getY());
        }
    }

    public void mouseReleased(MouseEvent e) {
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    public void treeExpanded(TreeExpansionEvent event) {
        TreeNode node = getNodeFromEvent(event);

        if (node instanceof ClassTreeNode)
            expandedClasses.add(node);
    }

    public void treeCollapsed(TreeExpansionEvent event) {
        TreeNode node = getNodeFromEvent(event);

        if (node instanceof ClassTreeNode)
            expandedClasses.remove(node);
    }

    private TreeNode getNodeFromEvent(TreeExpansionEvent event) {
        return (TreeNode) event.getPath().getLastPathComponent();
    }
}
